1 /*
2 * Title: S/MIME Project
3 * Description: S/MIME email sending capabilities
4 * @Author Vladan Obradovic
5 * @Version 2.0.1
6 */
7
8 package org.webdocwf.util.smime.smime;
9
10
11 import org.webdocwf.util.smime.exception.SMIMEException;
12 import org.webdocwf.util.smime.exception.ErrorStorage;
13 import org.webdocwf.util.smime.activation.CMSEnvelopedDataSource;
14 import org.webdocwf.util.smime.activation.StreamDataSource;
15 import org.webdocwf.util.smime.mail.MultipartGenerator;
16 import org.webdocwf.util.smime.util.MimeAssist;
17 import org.webdocwf.util.smime.util.ConvertAssist;
18 import javax.mail.internet.HeadersUtil;
19 import javax.mail.Session;
20 import javax.mail.Message;
21 import javax.mail.Multipart;
22 import javax.mail.Transport;
23 import javax.mail.MessagingException;
24 import javax.mail.internet.MimeMessage;
25 import javax.mail.internet.MimeBodyPart;
26 import javax.mail.internet.MimeMultipart;
27 import javax.mail.internet.InternetAddress;
28 import javax.activation.DataHandler;
29 import javax.activation.FileDataSource;
30 import javax.activation.MimetypesFileTypeMap;
31 import java.util.Vector;
32 import java.util.Properties;
33 import java.util.SimpleTimeZone;
34 import java.util.GregorianCalendar;
35 import java.io.File;
36 import java.io.FileInputStream;
37 import java.io.InputStream;
38 import java.io.ByteArrayInputStream;
39 import java.security.Security;
40 import java.security.cert.X509Certificate;
41 import java.security.cert.CertificateFactory;
42 import sun.security.provider.Sun;
43 import org.bouncycastle.jce.provider.BouncyCastleProvider;
44
45
46 /***
47 * EnvelopedSMIME class is used for creating and sending encrypted S/MIME
48 * message.<BR>
49 * <BR>
50 * Email message is in general composed of the content of the message and of one or
51 * more attachments. The content is visible part of the message, and attacments are
52 * mostly files or other binary data, which are not visible parts of message and
53 * which are used by email as a transport medium. In this implementation content
54 * can be represented in two different forms: <BR>
55 * <BR>
56 * <UL><LI>
57 * text/plain (only text withouth any formating) or
58 * </LI> <LI>
59 * text/html (html coded view of message)
60 * </LI></UL>
61 * Also, content can be absent, but than at least one attachment must be added.
62 * Content can be set on few manners. For text/plain type it can be done in time
63 * of construction with constructor designed special for creation of text/plain
64 * messages. Also, text content can be created by any of setContent() methods,
65 * if construction of object was done by other constructor which create object
66 * with empty content. Construction with other constructor offers a few different
67 * posibilities for importing content data (File, InputStream, String) by using
68 * appropriate setContent() method. If method with four parameters is used, 3rd
69 * ant 4th parameters are not in use for text/plain message and could be set
70 * null. For setting text/html content, construction of object should be done
71 * only by second mentioned constructor, which creates object with empty content.
72 * Content should be populated by html code with setContent() method. 3rd
73 * parameter is used for resolving relative addresses of resources in html
74 * code (images, movies...) and 4th parameter serves as data source for resources
75 * that are on special way addressed in html code. Also, there is a setContent()
76 * method which doesn't care about resources and which creates message content
77 * withouth them. For more information refer to setContent() methods.<BR>
78 * <BR>
79 * Message can contain any number of attachments. Also, message can
80 * be wihouth any attachment, but then content must be present. Every attachment
81 * should be added by performing single addAttachment() method. Attachments
82 * can be added from file or from InputStream. Mime-type which corresponds to
83 * particular attachment is obtained according to extension of file name
84 * (virtual or real file name) passed to addAttachment() method. File mime.types
85 * in META_INF directory contains list of mime-types and corresponding extensions
86 * which are used in determination of mime-type. File can be changed to satisfy
87 * secific requrements. For more information refer to addAttachmenttent()
88 * method.<BR>
89 * <BR>
90 * Encryption of message is performed by symmetric encryption with random
91 * generated symmetric key. This key is then encrypted by assymetric encryption
92 * with a recipient's public key, and sent together with encrypted message to
93 * recipient in CMS (Cryptographic Message Syntax) enveloped object. For all
94 * recipients of the message (if there is more than one) operation of encrypting
95 * symmetric key must be performed with his corresponding public key (from .cer
96 * file). Encryption can be performed by following algorithms and corresponding
97 * key sizes:<BR>
98 * <BR>
99 * RC2_CBC, 40 bits (default encryption)<BR>
100 * RC2_CBC, 64 bits<BR>
101 * RC2_CBC, 128 bits<BR>
102 * DES, 56 bits<BR>
103 * DES_EDE3_CBC, 128 bits<BR>
104 * DES_EDE3_CBC, 192 bits<BR>
105 * <BR>
106 * As a asymmetric algorithm, RSA algorithm is used.<BR>
107 * <BR>
108 */
109 public class EnvelopedSMIME {
110
111 /***
112 * Container for MIME message
113 */
114 private MimeMessage message;
115
116 /***
117 * Storage for .cer files coresponding to appropriate enveloping session
118 */
119 private Vector certArray = new Vector(0, 1);
120
121 /***
122 * Storage for MIME bodyparts
123 */
124 private Vector bodyPartArray = new Vector(0, 1);
125
126 /***
127 * Indication that at least one recipient must be TO (others may be CC or BCC)
128 */
129 private boolean indicatorTo = false;
130
131 /***
132 * Indicator of the presence of plain text content
133 */
134 private boolean textContentPresence = false;
135
136 /***
137 * Initializes the JavaMail session for SMTP and the MimeMessage for encryption.
138 * Dynamically loads the BC and SUN provider necessary for encryption. This
139 * constructor is used for creating message with text/plain content. For creating
140 * html formated content (text/html), other constructor should be used in
141 * combination with one of setContent methods. Note that after using this
142 * constructor setContent method can be used only if "content" argument of
143 * constructor was given as null, otherwise setContent method can't be used
144 * because content is already set as text/plain.
145 * @param smtpHost name of SMTP host used for sending email
146 * @param fromAddress email address of sender (FROM field in email header)
147 * @param subject subject of email (SUBJECT field in email header)
148 * @param content text/plain content of email message
149 * @exception SMIMEException if smtpHost or fromAddress parameters are null.
150 * Also, it can be caused by non SMIMEException which is MessagingException.
151 */
152 public EnvelopedSMIME(String smtpHost, String fromAddress, String subject,
153 String content) throws SMIMEException {
154 try {
155 Security.addProvider(new BouncyCastleProvider()); // Dynamic loading the BC provider
156 Security.addProvider(new Sun()); // Dynamic loading the SUN provider necessary for SHA1withRSA
157
158 if (smtpHost == null | fromAddress == null)
159 throw new SMIMEException(this, 1041);
160 Properties sesProp = new Properties();
161
162 sesProp.setProperty("mail.smtp.host", smtpHost);
163 Session ses = Session.getInstance(sesProp);
164
165 message = new MimeMessage(ses);
166 InternetAddress from = new InternetAddress(fromAddress);
167
168 message.setFrom(from);
169 if (subject != null)
170 message.setSubject(subject);
171 if (content != null) {
172 MimeBodyPart mbp = new MimeBodyPart();
173
174 mbp.setText(content);
175 bodyPartArray.addElement(mbp);
176 textContentPresence = true;
177 }
178 } catch (Exception e) {
179 throw SMIMEException.getInstance(this, e, "constructor");
180 }
181 }
182
183 /***
184 * Initializes the JavaMail session for SMTP and the MimeMessage for encryption.
185 * Dynamically loads the BC and SUN provider necessary for encryption. This
186 * constructor does not create content of message and it can be set later with
187 * one of setContent methods. Also, message can be left withouth content, but
188 * then at least one attachement must be added.
189 * @param smtpHost name of SMTP host used for sending email
190 * @param fromAddress email address of sender (FROM field in email header)
191 * @param subject subject of email (SUBJECT field in email header)
192 * @exception SMIMEException if smtpHost or fromAddress parameters are null.
193 * Also, it can be caused by non SMIMEException which is MessagingException.
194 */
195 public EnvelopedSMIME(String smtpHost, String fromAddress, String subject)
196 throws SMIMEException {
197 this(smtpHost, fromAddress, subject, null);
198 }
199
200 /***
201 * Sets message content. Message content can be given in two differrent forms:
202 * text and html code. If content is type of text, parameter "type" should be
203 * "text/plain" and other two parameters are not in use (should be set null).
204 * If content is type of html code, parameter "type" should be set as "text/html",
205 * otherwise (if it is set as "text/plain") html code is processed as a plain
206 * text. This method can be performed only once.<BR>
207 * <BR>
208 * In case of html content, it is essential to (on appropriate way) associate some
209 * attributes of particular elements in html code ("background" or "src" atributes)
210 * with corresponding ressources (URL-s, relative file addresses or byte array
211 * streams). This resources should all be sent with message to enable recipient
212 * to see complete html message. Location of resources can be given in few
213 * different forms and depending on that, allocation resolving can be successful or
214 * not. Following text represents different possibilities for defining locations
215 * of resources (pictures, animations, sound...) inside of html code passed to
216 * this method, and necessery passed additional parameters used for resolving
217 * this resource locations.<BR>
218 * <BR>
219 * <UL>
220 * <LI>URL defined as: http://... is left unchanged. This resource is not sent
221 * with the message and it couldn't be seen by recipient if it is not online on
222 * the internet.</LI>
223 * <LI>URL defined as: file://... is transformed to corresponding Content ID if
224 * the resource can be found on specified location and it is sent with message.</LI>
225 * <LI>Absolute path, for example defined as: "c:\tmp\test\picture.bmp", is
226 * transformed to corresponding Content ID if the resource can be found on
227 * specified location, and is sent with message. If all resources in html
228 * code are specified with its absolute path, the 3rd parameter in this method
229 * can be null.</LI>
230 * <LI>Relative path of all resources specified in html code, for example
231 * defined as: ".\test\picture.bmp" and ".\example\flush.swf", must be defined
232 * to be relative to same directory path (in this case it is c:\tmp). This parameter
233 * (common directory path) is given as 3rd parameter in this method, and is named
234 * "path". If html code is obtained from .html file, necessery common directory
235 * path is usually path to this .html file. Location of resource is transformed
236 * to corresponding Content ID if the resource can be found on specified location.
237 * This location is sent with the message.</LI>
238 * <LI>Byte array stream as resource for html attribute must be referenced from
239 * html code as: <BR>
240 * <BR><PRE>
241 * *****nnn<virtual_file_name><BR>
242 * <BR></PRE>
243 * Five '*' characters (must be five) define that it is resource expected from
244 * the stream. Other three characters must be digits (000-999) and represent
245 * index of corresponding stream in stream array. virtual_file_name is name and
246 * extension assigned to data passed from stream. Name is used in construction of
247 * "name" parameter in Content-Type, while extension of file name is used in
248 * detection of appropriate mime-type. Lenght of virtual_file_name is not
249 * important. If there is no data referenced from byte array stream ,4th
250 * parameter of this method named "resources" can be null. Also, if all resources
251 * are passed through the array of streams, 3th parameter ("path") can be null.
252 * Location of resource is transformed to corresponding Content ID if no error
253 * has occured during the process of allocation.</LI>
254 * </UL>
255 * <BR>
256 * All mentioned resource allocation types can be combined together in the same
257 * html code, and all will be processed with appropriate use of this method.<BR>
258 * <BR>
259 * Note that number of resource references that are defined in html code by
260 * using virtual_file_names must be greater than or equal to number of elements
261 * in array of InputStream (4th parameter). If one resource (one element in array
262 * of IputStream) is used in html code more than once, it is advisable to use
263 * same virtual_file_name in html code because message is then sent with only
264 * one attached resource (image, movie...). It is essetntial that desired resource
265 * in input stream array corresponds to specified "nnn" part of virtual_file_name.<BR>
266 * <BR>
267 * If resources specified on any described name can not be found or resolved,
268 * or if any exception has occured during its processing, they won't be added and
269 * html message will be sent withouth them.
270 * @param content String representation of message content (text or html code).
271 * @param type type of given content. It can take values: "text/plain" or
272 * "text/html".
273 * @param path common directory path for relative file locations in html code.
274 * It can be null if all resources set absolute path or are defined by
275 * byte array streams, or if sending resources with relative address it is not desired.
276 * Also, it is set to null in case of text/plain message.
277 * @param resources way for representing resources used in the given html code
278 * which will be added to message as array of InputStream. Detail use
279 * of this argument is described above. It can be null if no resources as byte
280 * array stream are used, or if sending resources given in that way is not desired.
281 * Also, it is set to null in case of text/plain message.
282 * @exception SMIMEException if content is tried to be added twice, or in case of
283 * wrong "type" parameter. Also, it can be caused by non SMIMEException which can
284 * be one of the following: MessagingException UnsoportedEncodingException.
285 */
286 public void setContent(String content, String type, String path,
287 InputStream[] resources) throws SMIMEException {
288
289 if (content != null) {
290 ByteArrayInputStream bais = null;
291
292 try {
293 bais = new ByteArrayInputStream(content.getBytes("ISO-8859-1"));
294 } catch (Exception e) {
295 throw SMIMEException.getInstance(this, e, "setContent");
296 }
297 this.setContent(bais, type, path, resources);
298
299 } else
300 throw new SMIMEException(this, 1035);
301 }
302
303 /***
304 * Sets message content from InputStream. This method can be performed only once.
305 * Message content can be given in two differrent forms: text and html code. If
306 * content is type of text, parameter "type" should be "text/plain", while if
307 * content is type of html code, parameter "type" should be set as "html/code".
308 * For further information refer to setContent method with four arguments
309 * (String, String, String, InputStream[] ) which is called by this method.
310 * @param content message content data given from any InputStream.
311 * Data can be text or html code and will be interpreted according to second
312 * parameter: "type".
313 * @param type type of given content. It can take values: "text/plain" or
314 * "text/html".
315 * @param path common directory path for relative file locations in html code.
316 * It can be null if all resources in html code have set absolute path or are
317 * defined by byte array streams, or if sending resources with relative address
318 * is not desired. Also, it is set to null in case of text/plain message.
319 * @param resources way for representing resources used in the given html code
320 * which will be added to message as array of InputStreams. Detail use
321 * of this argument is described in other setContent methods mentioned before.
322 * It can be null if no resources as byte array stream are used, or if sending
323 * resources given in that way is not desired. Also, it is set to null in case
324 * of text/plain message.
325 * @exception SMIMEException if content is tried to be added twice , in case of
326 * wrong "type" parameter or in case when parameter content is null. Also, it can
327 * be caused by non SMIMEException which is MessagingException.
328 */
329 public void setContent(InputStream content, String type, String path,
330 InputStream[] resources) throws SMIMEException {
331 if (textContentPresence)
332 throw new SMIMEException(this, 1049);
333 if (content != null) {
334 try {
335 if (type.equalsIgnoreCase("text/plain")) {
336 MimeBodyPart mbp = new MimeBodyPart();
337 String temp = new String(ConvertAssist.inStreamToByteArray(content), "ISO-8859-1");
338
339 mbp.setText(temp, "ISO-8859-1");
340 bodyPartArray.add(0, mbp);
341 textContentPresence = true;
342 } else if (type.equalsIgnoreCase("text/html")) {
343 MimeMultipart htmlMultipart =
344 MultipartGenerator.getHtmlMultipart(content, path, resources);
345
346 bodyPartArray.add(0, htmlMultipart);
347 textContentPresence = true;
348 } else
349 throw new SMIMEException(this, 1048);
350 } catch (Exception e) {
351 throw SMIMEException.getInstance(this, e, "setContent");
352 }
353 } else
354 throw new SMIMEException(this, 1035);
355 }
356
357 /***
358 * Sets message content from InputStream. This method can be performed only once.
359 * Message content can be given in two differrent forms: text and html code. If
360 * content is type of text, parameter "type" should be "text/plain", while if
361 * content is type of html code, parameter "type" should be set as "html/code".
362 * If html code content is set by this method, message will be generated withouth
363 * inclusion of the resources defined in paricular html element's attribute ("src" and
364 * "background"). Only plain html code will be sent and any reference to local
365 * file system resources will be useless for recipient of the message. HTTP referenced
366 * resources can still be available if recipient is online on Internet. Message
367 * generated on this way is smaller so encrypting process should be faster.
368 * @param content message content data given from any InputStream.
369 * Data could be text or html code and will be interpreted according to second
370 * parameter: "type".
371 * @param type type of given content. It can take values: "text/plain" or
372 * "text/html".
373 * @exception SMIMEException if content is tried to be added twice , in case of
374 * wrong "type" parameter or in case when parameter content is null. Also, it can
375 * be caused by non SMIMEException which is MessagingException.
376 */
377 public void setContent(InputStream content, String type) throws SMIMEException {
378 if (textContentPresence)
379 throw new SMIMEException(this, 1049);
380 if (content != null) {
381 try {
382 if (type.equalsIgnoreCase("text/plain")) {
383 MimeBodyPart mbp = new MimeBodyPart();
384 String temp = new String(ConvertAssist.inStreamToByteArray(content), "ISO-8859-1");
385
386 mbp.setText(temp, "ISO-8859-1");
387 bodyPartArray.add(0, mbp);
388 textContentPresence = true;
389 } else if (type.equalsIgnoreCase("text/html")) {
390 MimeMultipart htmlMultipart =
391 MultipartGenerator.getHtmlMultipart(content);
392
393 bodyPartArray.add(0, htmlMultipart);
394 textContentPresence = true;
395 } else
396 throw new SMIMEException(this, 1048);
397 } catch (Exception e) {
398 throw SMIMEException.getInstance(this, e, "setContent");
399 }
400 } else
401 throw new SMIMEException(this, 1035);
402 }
403
404 /***
405 * Sets message content from String. This method can be performed only once.
406 * Message content can be given in two differrent forms: text and html code. If
407 * content is type of text, parameter "type" should be "text/plain", while if
408 * content is type of html code, parameter "type" should be set as "html/code".
409 * If html code content is set by this method, message will be generated withouth
410 * inclusion of the resources defined in paricular html element's attribute ("src" or
411 * "background"). Only plain html code will be sent and any reference to local
412 * file system resources will be useless for recipient of the message. HTTP referenced
413 * resources can still be available if recipient is online on Internet. Message
414 * generated on this way is smaller, so encrypting process should be faster.
415 * @param content message content data given as String which can
416 * be text or html code and will be interpreted according to second parameter:
417 * "type".
418 * @param type type of given content. It can take values: "text/plain" or
419 * "text/html".
420 * @exception SMIMEException if content is tried to be added twice, or in case of
421 * wrong "type" parameter. Also, it can be caused by non SMIMEException which can
422 * be one of the following: MessagingException UnsoportedEncodingException.
423 */
424 public void setContent(String content, String type) throws SMIMEException {
425
426 if (content != null) {
427 ByteArrayInputStream bais = null;
428
429 try {
430 bais = new ByteArrayInputStream(content.getBytes("ISO-8859-1"));
431 } catch (Exception e) {
432 throw SMIMEException.getInstance(this, e, "setContent");
433 }
434 this.setContent(bais, type);
435
436 } else
437 throw new SMIMEException(this, 1035);
438 }
439
440 /***
441 * Sets message content from file represented by File object. This method can be
442 * performed only once. Message content can be given in two differrent forms:
443 * text and html code. If content is type of text, parameter "type" should be
444 * "text/plain", while if content is type of html code, parameter "type" should
445 * be set as "html/code". For further information refer to setContent method
446 * with four arguments (String, String, String, InputStream[] ) which is called
447 * by this method.
448 * @param inFile location of file which is used for content of the message
449 * @param type type of given content. It can take values: "text/plain" or
450 * "text/html".
451 * @exception SMIMEException if content is tried to be added twice, in case of
452 * wrong "type" parameter, or if passed file (as File object) does not exist in
453 * file sistem. Also, it can be caused by non SMIMEException which can be one of
454 * the following: MessagingException or IOException.
455 */
456 public void setContent(File inFile, String type) throws SMIMEException {
457
458 if (textContentPresence)
459 throw new SMIMEException(this, 1049);
460 if (inFile != null && inFile.exists()) {
461 try {
462 File inFileAbs = inFile.getAbsoluteFile().getCanonicalFile();
463 String content = ConvertAssist.readFileToString(inFileAbs);
464
465 this.setContent(content, type, inFile.getParent(), null);
466 } catch (Exception e) {
467 throw SMIMEException.getInstance(this, e, "setContent");
468 }
469 } else
470 throw new SMIMEException(this, 1034);
471 }
472
473 /***
474 * Sets REPLY TO field in message header
475 * @param replyAddress email address used to reply
476 * @exception SMIMEException caused by non SMIMEException which is
477 * MessagingException. Also, javax.mail.internet.AddressException is thrown
478 * from instances of InternetAddress class (but AddressException extends
479 * MessagingException).
480 */
481 public void setReply(String replyAddress) throws SMIMEException {
482 try {
483 InternetAddress reply[] = new InternetAddress[1];
484
485 reply[0] = new InternetAddress(replyAddress);
486 message.setReplyTo(reply);
487 } catch (Exception e) {
488 throw SMIMEException.getInstance(this, e, "addRecipient");
489 }
490 }
491
492 /***
493 * Adds recipient address, type and .cer file of email recipient to encrypted
494 * message.
495 * @param recipientAddress email address of recipent (fields TO or CC or BCC
496 * in email message header)
497 * @param type should be TO, CC or BCC
498 * @param cerFileName path and file name with certificate corresponding
499 * to recipient (file with .cer extension)
500 * @exception SMIMEException if type of addressing of messages is not TO, CC
501 * or BCC.
502 * @exception SMIMEException caused by non SMIMEException which is
503 * MessagingException.
504 */
505 public void addRecipient(String recipientAddress, String type, String cerFileName)
506 throws SMIMEException {
507 try {
508 if (!type.equalsIgnoreCase("TO") & !type.equalsIgnoreCase("BCC") & !type.equalsIgnoreCase("CC"))
509 throw new SMIMEException(this, 1042);
510 if (type.equalsIgnoreCase("TO")) {
511 message.addRecipients(Message.RecipientType.TO, recipientAddress);
512 indicatorTo = true;
513 } else if (type.equalsIgnoreCase("CC"))
514 message.addRecipients(Message.RecipientType.CC, recipientAddress);
515 else if (type.equalsIgnoreCase("BCC"))
516 message.addRecipients(Message.RecipientType.BCC, recipientAddress);
517 } catch (Exception e) {
518 throw SMIMEException.getInstance(this, e, "addRecipient");
519 }
520 certArray.addElement(cerFileName); // adding location of .cer file in stack
521 }
522
523 /***
524 * Adds file as attachment to email message
525 * @param fileName path and file name used for attachment
526 * @exception SMIMEException if passed file (as File object) does not exist in
527 * file sistem. Also, it can be caused by non SMIMEException which is
528 * MessagingException
529 */
530 public void addAttachment(String fileName) throws SMIMEException {
531 File fn = new File(fileName);
532
533 this.addAttachment(fn);
534 }
535
536 /***
537 * Adds file as attachment to email message
538 * @param file used for attachment represented as File object
539 * @exception SMIMEException if passed file (as File object) does not exist in
540 * file sistem. Also, it can be caused by non SMIMEException which is
541 * MessagingException
542 */
543 public void addAttachment(File file) throws SMIMEException {
544 if (!file.exists())
545 throw new SMIMEException(this, 1034);
546 MimeBodyPart attachment = new MimeBodyPart();
547 FileDataSource fd = new FileDataSource(file);
548
549 try {
550 attachment.setDataHandler(new DataHandler(fd));
551 attachment.setDisposition(attachment.ATTACHMENT);
552 attachment.setFileName(file.getName());
553 } catch (Exception e) {
554 throw SMIMEException.getInstance(this, e, "addAttachment");
555 }
556
557 bodyPartArray.addElement(attachment);
558 }
559
560 /***
561 * Adds data from InputStream as attachment to email message
562 * @param data byte array from InputStream
563 * @param fileName virtual or real file name (wihouth path). Correct information
564 * about name; extension of file name is especially important. Name
565 * is used in construction of "name" parameter in Content-Type header line of
566 * body parts of mime message. Extension of file is used in detection of
567 * appropriate mime-type.
568 * @exception SMIMEException caused by non SMIMEException which is
569 * MessagingException
570 */
571 public void addAttachment(InputStream data, String fileName) throws SMIMEException {
572 MimeBodyPart attachment = new MimeBodyPart();
573
574 try {
575 attachment.setDataHandler(new DataHandler(new StreamDataSource(data, fileName)));
576 attachment.setDisposition(attachment.ATTACHMENT);
577 attachment.setFileName(fileName);
578 bodyPartArray.addElement(attachment);
579 } catch (Exception e) {
580 throw SMIMEException.getInstance(this, e, "addAttachment");
581 }
582 }
583
584 /***
585 * Envelopes message with default algorithm RC2_CBC, 40 bits
586 * @exception SMIMEException if one of recipients is not declared as TO
587 * recipient, or if there is no message for enveloping. Also, it can be caused
588 * by non SMIMEException which can be one of the following: CertificateException,
589 * IOException, MessagingException or FileNotFoundException.
590 */
591 public void enveloping() throws SMIMEException {
592 this.enveloping("RC2_CBC", 40);
593 }
594
595 /***
596 * Envelopes message with given algorithm name and key length
597 * @param algorithmName name of chosen algorithm used for encryption
598 * @param keyLength key size in bits
599 * @exception SMIMEException if one of recipients is not declared as TO
600 * recipient, or if there is no message for enveloping. Also, it can be caused
601 * by non SMIMEException which can be one of the following: CertificateException,
602 * IOException, MessagingException or FileNotFoundException.
603 */
604 public void enveloping(String algorithmName, int keyLength) throws SMIMEException {
605 try {
606 if (indicatorTo != true)
607 throw new SMIMEException(this, 1043);
608 if (textContentPresence & bodyPartArray.size() == 1) { // message contains only content
609 if (bodyPartArray.elementAt(0) instanceof MimeBodyPart) { // text/plain message
610 MimeBodyPart contentBody = (MimeBodyPart) bodyPartArray.elementAt(0);
611
612 message.setContent((String) contentBody.getContent(), contentBody.getContentType());
613 message.setDisposition(message.INLINE);
614 } else // text/html message
615 message.setContent((MimeMultipart) bodyPartArray.elementAt(0));
616 } else if (bodyPartArray.size() != 0) {
617 Multipart mp = new MimeMultipart();
618
619 for (int i = 0; i != bodyPartArray.size(); i++) {
620 if (bodyPartArray.elementAt(i) instanceof MimeMultipart) {
621 MimeBodyPart forMulti = new MimeBodyPart();
622
623 forMulti.setContent((MimeMultipart) bodyPartArray.elementAt(i));
624 mp.addBodyPart(forMulti);
625 } else
626 mp.addBodyPart((MimeBodyPart) bodyPartArray.elementAt(i));
627 }
628 message.setContent(mp);
629 } else
630 throw new SMIMEException(this, 1044);
631
632 CMSEnvelopedDataSource es = new CMSEnvelopedDataSource(message, algorithmName, keyLength);
633
634 for (int i = 0; i != certArray.size(); i++) {
635 InputStream inStream = new FileInputStream((String) (certArray.elementAt(i)));
636 CertificateFactory cf = CertificateFactory.getInstance("X.509");
637 X509Certificate cert = (X509Certificate) cf.generateCertificate(inStream);
638
639 inStream.close();
640 es.addRecipient(cert);
641 }
642
643 message.setDataHandler(new DataHandler(es));
644 HeadersUtil.updateHeaders(message);
645 message.setDescription("Enveloped SMIME message.");
646 message.setDisposition(message.ATTACHMENT);
647 SimpleTimeZone tz = (SimpleTimeZone) SimpleTimeZone.getDefault(); // Sets date and time
648 GregorianCalendar cal = new GregorianCalendar(tz);
649
650 message.setSentDate(cal.getTime());
651
652 clean();
653 } catch (Exception e) {
654 throw SMIMEException.getInstance(this, e, "enveloping");
655 }
656 }
657
658 /***
659 * Returns SMIME Message
660 * @return Enveloped S/MIME message
661 */
662 public MimeMessage getEnvelopedMessage() {
663 return message;
664 }
665
666 /***
667 * Sends S/MIME message to SMTP host
668 * @exception MessagingException caused by use of methods from objects of class
669 * Transport.
670 */
671 public void send() throws MessagingException {
672 Transport.send(message);
673 }
674
675 /***
676 * Releases unnecessary memory
677 */
678 private void clean() {
679 bodyPartArray = null;
680 certArray = null;
681 System.gc(); // Calling garbage collector
682 }
683
684 }
685
This page was automatically generated by Maven